#ifndef _CRT_COMMON_HPP_
#define _CRT_COMMON_HPP_

#ifndef _OFF_T_DEFINED
#define _OFF_T_DEFINED
typedef long _off_t;
#endif

#ifdef CPP_NO_VTABLE
#undef CPP_NO_VTABLE
#endif

#if defined(_MSC_VER)
#define CPP_NO_VTABLE __declspec(novtable)
#else
#define CPP_NO_VTABLE
#endif

#if (OS_COMPILER == CC_MSVC)
#define __attribute__(x)
#elif (OS_COMPILER == CC_GCC)

#endif

#if (OS_COMPILER == CC_MSVC)
#define _aligned(g) __declspec(align(g))
#else
#define _aligned(g) __attribute__((aligned(g)))
#endif

#ifndef __aligned
#define __aligned(g, type) _aligned(g) type
#endif

#define PACK_ONEBYTE   __attribute__((packed))
#define PACK_EIGHTBYTE __attribute__((aligned(8)))

#if (TARGET_OS == OS_WIN)
#define _unused
#define _VISIBILITY_DEFAULT
#define _VISIBILITY_HIDDEN
#elif (TARGET_OS == OS_POSIX)
#define _unused             __attribute__((__unused__))
#define _VISIBILITY_DEFAULT __attribute__((visibility("default")))
#define _VISIBILITY_HIDDEN  __attribute__((visibility("hidden")))
#elif (TARGET_OS == OS_MACH)
#define _unused             __attribute__((__unused__))
#define _VISIBILITY_DEFAULT __attribute__((visibility("default")))
#define _VISIBILITY_HIDDEN  __attribute__((visibility("hidden")))
#elif (TARGET_OS == OS_UNIX)
#define _unused             __attribute__((__unused__))
#define _VISIBILITY_DEFAULT __attribute__((visibility("default")))
#define _VISIBILITY_HIDDEN  __attribute__((visibility("hidden")))
#endif

#if (TARGET_OS == OS_WIN)
#define path_slash _T("\\")
#elif (TARGET_OS == OS_POSIX)
#define path_slash _T("/")
#elif (TARGET_OS == OS_MACH)
#define path_slash _T("/")
#elif (TARGET_OS == OS_UNIX)
#define path_slash _T("/")
#endif

#ifdef __cplusplus
#ifndef EXTERN_C
#define EXTERN_C extern "C"
#endif

#define static_inline inline
#define static_const  static const

#ifndef interface
#define interface struct
#endif

#else
#ifndef EXTERN_C
#define EXTERN_C extern
#endif

#if (TARGET_OS == OS_WIN)
#define inline _inline
#endif

#define static_inline static inline
#define static_const  static const

#ifndef interface
#define interface typedef struct
#endif

#ifdef CONST_VTABLE
#define CONST_VTBL const
#else
#define CONST_VTBL
#endif

#define bool _Bool
#define false 0
#define true 1

#endif /* __cplusplus */

#if (TARGET_OS == OS_WIN)
#define OS_STDCALL                      WINAPI
#define OS_CALLBACK_(_type, _name)      _type(WINAPI* _name)
#define _stdmethod_export(type, method) EXTERN_C type OS_STDCALL method
#elif (TARGET_OS == OS_POSIX)
#define OS_STDCALL
#define OS_CALLBACK_(_type, _name)      _type(OS_STDCALL* _name)
#define _stdmethod_export(type, method) EXTERN_C type _VISIBILITY_DEFAULT method
#elif (TARGET_OS == OS_MACH)
#define OS_STDCALL
#define OS_CALLBACK_(_type, _name)      _type(OS_STDCALL* _name)
#define _stdmethod_export(type, method) EXTERN_C type _VISIBILITY_DEFAULT method
#elif (TARGET_OS == OS_UNIX)
#define OS_STDCALL
#define OS_CALLBACK_(_type, _name)      _type(OS_STDCALL* _name)
#define _stdmethod_export(type, method) EXTERN_C type _VISIBILITY_DEFAULT method
#endif

typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;

#if (TARGET_OS == OS_WIN)

typedef __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef __int64 int64;

typedef unsigned __int8 uint8;
typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
typedef unsigned __int64 uint64;

#define fmt_i64d "%I64d"
#define fmt_i64u "%I64u"

#elif (TARGET_OS == OS_POSIX)

typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;

typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;

// #define int64		long long int
// #define uint64		unsigned long long int

#define fmt_i64d "%lld"
//"%" PRId64

#if defined(ANDROID)
#define fmt_i64u "%lu"
#else
#define fmt_i64u "%llu"
#endif

#elif (TARGET_OS == OS_MACH)

typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;

typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;

#define fmt_i64d "%lld"
#define fmt_i64u "%llu"

#elif (TARGET_OS == OS_UNIX)

typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;

typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;

#define fmt_i64d "%lld"
#define fmt_i64u "%llu"

#endif

#endif
